home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / xnot12a.zip / W3IO.C < prev    next >
C/C++ Source or Header  |  1993-06-11  |  11KB  |  513 lines

  1. #ifdef MSW /** WHOLE FILE **/
  2.  
  3. /* Munged code from ttyio, changed as needed to interface to Windows
  4. * and pretend to be a terminal window. This was early porting work and
  5. * shows it; I took the existing code and just hacked it to work. Some
  6. * new functions were added if they felt like they belonged in this file.
  7. *
  8. * NOTE that for Windows I created a routine (ttputline) and turned
  9. * off the GOSLING code.  Much less compute intensive, and on my 486
  10. * I get much better performance just redrawing everything as opposed to
  11. * trying to figure out which lines of the screen can be moved, moving them 
  12. * and redrawing around the moved lines. Define GOSLING if you want (see 
  13. * ttydef.h) to see which runs best on your system.  There is code in here 
  14. * to support either option.
  15. */  
  16. #include "jam.h"
  17.   
  18. /*
  19.  * Window 3.1 interface
  20.  */
  21. #include    "def.h"
  22.  
  23. int    tceeol = 0   /* 2 */;           /* very cheap */
  24. int    tcinsl = 2   /* 5 */;
  25. int    tcdell = 2   /* 5 */;
  26.  
  27. static int bioscol = -1;        /* cursor column */
  28. static int curcolor = -1;
  29.  
  30. #ifdef GOSLING
  31. static void WindowMoveLines(int row, int bot, int num, int up);
  32. #endif
  33.  
  34. static void rn_(putthechar,(unsigned char  c));
  35.  
  36. /* Erase window content
  37.  */
  38. void WindowErase(void)
  39. {
  40.   RECT rect;
  41.   
  42.   if (edInited)
  43.     {
  44.       GetClientRect(g_hWnd, &rect);
  45.       ZapRect(&rect);
  46.       curcolor = -1;  /* force refresh rechecks system colors */
  47.     }
  48. }
  49.  
  50. /*
  51.  * Initialize the terminal when the editor
  52.  * gets started up.
  53.  */
  54. ttinit() 
  55. {
  56.   /* if notGNU were windows-aware, it would 
  57.   * do something here 
  58.   */  
  59.   return TRUE;        
  60. }
  61.  
  62. /*
  63.  * Clean up the terminal, in anticipation of
  64.  * a return to the command interpreter.
  65.  */
  66. tttidy() 
  67. {
  68.   return TRUE;
  69. }
  70.  
  71. /*
  72.  * Move the cursor to the specified
  73.  * origin 0 row and column position.
  74.  */
  75. ttmove(int row, int col) 
  76. {
  77.   ttcol = col;
  78.   ttrow = row;
  79.   
  80.   g_caret_x = col * g_nCharWidth;
  81.   g_caret_y = row * g_nLineHeight;
  82.   
  83.   /* make cursor up-to-date
  84.    */
  85. #ifdef WINDOWS_CURSOR
  86.   SetCaretPos(g_caret_x, g_caret_y);
  87. #endif
  88.   bioscol = col;
  89.   
  90.   return TRUE;
  91. }
  92.  
  93. /*
  94.  * Erase to end of page.
  95.  */
  96. tteeop() 
  97. {
  98.   if (edInited)
  99.     WindowZapLines(ttrow, nrow);
  100.   return TRUE;
  101. }
  102.  
  103. /* Generic fill-to-background function
  104. */
  105. void WindowZapLines(int row, int bot)
  106. {
  107.   RECT rect;
  108.   
  109.   GetClientRect(g_hWnd, &rect);
  110.   rect.top = row * g_nLineHeight;
  111.   rect.bottom = ((bot + 1) * g_nLineHeight)  - 1;
  112.   ZapRect(&rect);
  113. }
  114.  
  115. /*
  116.  * Insert nchunk blank line(s) onto the
  117.  * screen, scrolling the last line on the
  118.  * screen off the bottom.
  119.  */
  120. ttinsl(int row, int bot, int nchunk) 
  121. {
  122. #ifdef GOSLING
  123.   if (row == bot) 
  124.     {                            /* Case of one line insert is     */
  125.       ttmove(row, 0);        /*    special            */
  126.       tteeol();
  127.     }
  128.   else
  129.     WindowMoveLines(row, bot, nchunk, FALSE);
  130. #endif
  131.   return TRUE;
  132. }
  133.  
  134. /*
  135.  * Delete nchunk line(s) from "row", replacing the
  136.  * bottom line on the screen with a blank line. 
  137.  */
  138. ttdell(int row, int bot, int nchunk)
  139. {
  140. #ifdef GOSLING
  141.   if (row == bot)
  142.     {                         /* One line special case    */
  143.       ttmove(row, 0);
  144.       tteeol();
  145.     }
  146.   else
  147.     WindowMoveLines(row, bot, nchunk, TRUE);
  148. #endif
  149.   return TRUE;
  150. }
  151.  
  152. /*
  153.  * Switch to full screen scroll. This is
  154.  * used by "spawn.c" just before is suspends the
  155.  * editor, and by "display.c" when it is getting ready
  156.  * to exit.
  157.  */
  158. ttnowindow()
  159. {
  160.   return TRUE;
  161. }
  162.  
  163. /*
  164.  * Set the current writing color to the
  165.  * specified color. Watch for color changes that are
  166.  * not going to do anything (the color is already right)
  167.  * and don't send anything to the display.
  168.  *
  169.  * This code and text output in this file can ONLY work
  170.  * if this is the only place color is set!
  171.  * 
  172.  */
  173. ttcolor(color) 
  174. register int color; 
  175. {
  176.   if (curcolor != color)
  177.     {
  178.       curcolor = color;
  179.       if (color == CTEXT)
  180.     {
  181.       SetBkColor(g_hDC, GetBackColor());
  182.       SetTextColor(g_hDC, GetForeColor());
  183.     }
  184.       else if (color == CMODE)
  185.     {
  186.       SetBkColor(g_hDC, GetForeColor());
  187.       SetTextColor(g_hDC, GetBackColor());
  188.         }
  189.       else if (curcolor == CHIGH)
  190.         {
  191.           SetBkColor(g_hDC, GetBackColor());
  192.           SetTextColor(g_hDC, GetHighColor());
  193.         }
  194.     }
  195.   tthue = color;           /* Save the color.    */
  196.   return TRUE;
  197. }
  198.  
  199. /*
  200.  * This routine is called by the
  201.  * "refresh the screen" command to try and resize
  202.  * the display. The new size, which must be deadstopped
  203.  * to not exceed the NROW and NCOL limits, it stored
  204.  * back into "nrow" and "ncol". Display can always deal
  205.  * with a screen NROW by NCOL. Look in "window.c" to
  206.  * see how the caller deals with a change.
  207.  */
  208. ttresize() 
  209. {
  210.   int flag = 0;
  211.   
  212.   setttysize();
  213.   
  214.   if (nrow > NROW)
  215.     flag = nrow = NROW;
  216.   if (ncol > NCOL)
  217.     flag = ncol = NCOL;
  218.   
  219.   /* non-zero means reached a limit
  220.    */
  221.   if (flag)
  222.     WindowMessage("Internal limit: max rows/cols reached.", FALSE);
  223.   return TRUE;
  224. }
  225.  
  226. ttputc(c)
  227. unsigned char c;
  228. {
  229.   if (c == '\b')         /* odd the way this works.. */
  230.     {
  231.       if (bioscol-1 > 0) 
  232.     {
  233.       ttmove(ttrow, bioscol-1);
  234.     }
  235.       return(1);
  236.     }
  237.   else if (c == '\r')         /* this too... */
  238.     {
  239.       ttmove(ttrow, 0);
  240.       return(1);
  241.     }
  242.   
  243.   if (edInited)
  244.     putthechar(c);
  245.   
  246.   if (bioscol + 1 >= ncol)
  247.     ttmove(ttrow + 1, 0);
  248.   else
  249.     ttmove(ttrow, bioscol + 1);
  250.   return(TRUE);
  251. }
  252.  
  253. /*
  254.  * Erase to end of line.
  255.  */
  256. tteeol() 
  257. {
  258.   RECT rect;
  259.   
  260.   if (edInited)
  261.     {
  262.       GetClientRect(g_hWnd, &rect);
  263.       rect.top = g_caret_y;
  264.       rect.left = g_caret_x;
  265.       rect.bottom = rect.top + g_nLineHeight;
  266.       ZapRect(&rect);
  267.     }
  268.   return TRUE;
  269. }
  270.  
  271. /*
  272.  * Make a noise.
  273.  */
  274. ttbeep() 
  275. {
  276.   MessageBeep((UINT)-1);
  277.   return TRUE;
  278. }
  279.  
  280. /* Insert/delete num lines at row
  281.  */
  282. #ifdef GOSLING
  283. static void WindowMoveLines(int row, int bot, int num, int up)
  284. {
  285.   RECT scrollrect, clearrect;
  286.   int line, direction;
  287.   
  288.   if (up)
  289.     {
  290.       direction = -1; 
  291.       line = bot;
  292.     }
  293.   else /* down */
  294.     {
  295.       direction = 1;
  296.       line = row;
  297.     }
  298.  
  299.   /* Load rect with window size (inside the borders, menubar, etc)
  300.    */
  301.   GetClientRect(g_hWnd, &scrollrect);
  302.   
  303.   /* Reset height for target rows
  304.    */
  305.   scrollrect.top = row * g_nLineHeight;
  306.   scrollrect.bottom = (bot + 1) * g_nLineHeight;
  307.   ScrollWindowEx(g_hWnd, 0, (num * g_nLineHeight) * direction, 
  308.          &scrollrect, &scrollrect, 0, &clearrect, 0);
  309.   
  310.   WindowZapLines(line, line);
  311.   ZapRect(&clearrect);
  312. }
  313. #endif
  314.  
  315. /* Dump char to screen (window); mostly only for echo line
  316.  */
  317. #define LINESIZE (NCOL + 2)
  318. static char theLine[LINESIZE];
  319. static int theX, theY;
  320. static int theColor;
  321. static int theIndex = 0;
  322.  
  323. static void putthechar(unsigned char c)
  324. {
  325.   /* Flush text if buffer fills, color changes or position
  326.   * of new char is not directly following last char, on same line.
  327.   */
  328.   if ((theIndex + 1) >= LINESIZE)
  329.     ttcharflush();
  330.   else if (curcolor != theColor)
  331.     ttcharflush();
  332.   else if ((theX + (theIndex * g_nCharWidth)) != g_caret_x)
  333.     ttcharflush();
  334.   else if (theY != g_caret_y)
  335.     ttcharflush();
  336.   
  337.   /* Add new char to string.
  338.   */
  339.   if (theIndex == 0)    /* Save the start position, etc of new line */
  340.     {
  341.       theColor = curcolor;
  342.       theX = g_caret_x;
  343.       theY = g_caret_y;
  344.     }
  345.   theLine[theIndex++] = (char)c;
  346.   theLine[theIndex] = '\0';
  347. }
  348.  
  349. /* Dump whole line of text; called by redisplay code
  350. * and alternate echo (msg line) code
  351. */
  352. int ttputline(text)
  353. char *text;
  354. {
  355.   int len = strlen(text);
  356. #if 0  /* this code seems unneccessary, and is probably slower */
  357.   RECT rect;
  358.  
  359.   if (len)
  360.     {
  361.       rect.left = g_caret_x;
  362.       rect.top = g_caret_y;
  363.       rect.right = g_nCharWidth * ncol;        /* window will clip */
  364.       rect.bottom = rect.top + g_nLineHeight;
  365.       ExtTextOut(g_hDC, g_caret_x, g_caret_y, ETO_OPAQUE, &rect, text, len, 
  366.                  NULL);  
  367.     }
  368. #else
  369.   if (len)
  370.     ExtTextOut(g_hDC, g_caret_x, g_caret_y, 0, 0, text, len, NULL);  
  371. #endif
  372.   return(TRUE);
  373. }
  374.  
  375. ttwait()
  376. {
  377.   return(0);    /* nothing to wait for */
  378. }
  379.  
  380. /* Not perfectly nice, but ok. We know we have timer msgs
  381. * coming in every so often, so just count them out. Other 
  382. * messages (key presses) will be waiting for us in the input queue, so 
  383. * nothing is lost. Actually, except for the (sigh) input loop here vs
  384. * the 'real' loop in w3win.c, this is kinda alright.
  385. */
  386. void sleep(int amount)
  387. {
  388.   MSG msg;
  389.   int incs = 0;
  390.   
  391.   for (; g_idTimer && (amount > 0); )
  392.     {
  393.       if (GetMessage(&msg, 0, WM_TIMER, WM_TIMER))
  394.     {
  395.       TranslateMessage(&msg);
  396.       DispatchMessage(&msg);
  397.       incs++;
  398.       
  399.       /* how many secs?
  400.        */
  401.       if (incs == (INCS_PER_SLEEP))    /* if this is too big, we seem to hang */
  402.         {
  403.           amount--;
  404.           incs = 0;
  405.         }
  406.     }
  407.     }
  408. }
  409.  
  410. /* Erase a given rect
  411.  */
  412. void ZapRect(RECT *rect)
  413. {
  414.   HBRUSH hbrush;
  415.   COLORREF color = GetBackColor();
  416.   
  417.   hbrush = CreateSolidBrush(color);
  418.   FillRect(g_hDC, rect, hbrush);
  419.   DeleteObject(hbrush);
  420. }
  421.  
  422. /* Query for window size and convert it to
  423.  * rows and cols based on current font info
  424.  */
  425. void WindowGetSize(int *nrow, int *ncol)
  426. {
  427.   RECT rect;
  428.   int width, height;
  429.   
  430.   if (!IsIconic(g_hWnd))
  431.     {
  432.       GetClientRect(g_hWnd, &rect);  
  433.       width = rect.right - rect.left;
  434.       height = rect.bottom - rect.top;
  435.       *ncol = width/g_nCharWidth;
  436.       *nrow = height/g_nLineHeight;
  437.     }
  438.   else
  439.     {
  440.       *ncol = START_COLS;
  441.       *nrow = START_LINES;
  442.     }
  443. }
  444.  
  445. void WindowNewSize(row,col)
  446. int row,col;
  447. {
  448.   RECT rect;
  449.   GetWindowRect(g_hWnd, &rect);  
  450.   SizeWindow(rect.left, rect.top, col, row);
  451. }
  452.  
  453. /* (Re)size the window based on cols & rows
  454.  */
  455. void SizeWindow(int x, int y, int cols, int lines)
  456. {
  457.   int menu = 0;
  458.  
  459.   if (g_menu)
  460.     menu = GetSystemMetrics(SM_CYMENU);
  461.  
  462.   MoveWindow(g_hWnd, x, y, 
  463.          (g_nCharWidth * cols) + (2 * GetSystemMetrics(SM_CXFRAME)) 
  464. #ifdef VBAR
  465.              + GetSystemMetrics(SM_CXVSCROLL)
  466. #endif
  467.              ,
  468.          (g_nLineHeight * lines) + (2 * GetSystemMetrics(SM_CYFRAME)) + 
  469.          menu + GetSystemMetrics(SM_CYCAPTION), TRUE);
  470. }
  471. /* Draw marker based on cursor location; for drag select only.
  472.  * Must be xor!
  473.  */
  474. void DrawMarker()
  475. {
  476.   RECT rect;
  477.   BOOL wasVis = IsCaretVis();
  478.  
  479.   if (wasVis)
  480.     SetCaretVis(FALSE);
  481.   rect.left = g_caret_x;
  482.   rect.top = g_caret_y;
  483.   rect.bottom = rect.top + g_nLineHeight;
  484.   rect.right = rect.left + g_nCharWidth;
  485.   InvertRect(g_hDC, &rect);
  486.   if (wasVis)
  487.     SetCaretVis(TRUE);
  488. }
  489. void WindowSync()
  490.   /* noop on Win 3.1 */
  491. }
  492. void WindowFlush()
  493.   ttcharflush();    /* possible cached output chars */
  494.   /* no other Windows thing needed */
  495. }
  496. /* Flush any output, clear the string
  497. */
  498. void ttcharflush()
  499. {
  500.   if (theIndex >= 1)
  501.     {
  502.       int save_curcolor = curcolor;
  503.       ttcolor(theColor);
  504.       ExtTextOut(g_hDC, theX, theY, 0, 0, theLine, strlen(theLine), NULL);  
  505.       ttcolor(save_curcolor);
  506.       theLine[0] = '\0';
  507.       theIndex = 0;
  508.     }
  509. }
  510. #endif /* WHOLE FILE */
  511.